#!/bin/env python

class Dummy:
    def info(self, *msg):
        pass
    def warn(self, *msg):
        pass
    def error(self, *msg):
        pass
    def begin(self, *element):
        pass
    def end(self, *element):
        pass


class BasicXML:
    def info(self, *msg):
        self._commit_('<info>', msg, '</info>')
    def warn(self, *msg):
        self._commit_('<warn>', msg, '</warn>')
    def error(self, *msg):
        self._commit_('<error>', msg, '</error>')
    def begin(self, *element):
        self._commit_('<', element, '>')
    def end(self, *element):
        self._commit_('</', element, '>')
    def _join_(self, head, log, tail):
        return ''.join(head + [str(e) for e in log] + tail)
    def _commit_(self, head, log, tail):
        pass


class SimpleXML(BasicXML):
    xml = []
    def _commit_(self, head, log, tail):
        self.xml.append(self._join_([head], log, [tail]))
    def __iter__(self):
        return iter(self.xml)
    def __str__(self):
        return self.format(split='', indent=0)
    def format(self, split='\n', indent=1):
        if indent > 0:
            level = 0
            rtn = []
            for e in self.xml:
                if e[1] == '/':
                    level -= indent
                rtn.append(''.rjust(level) + e)
                if not '</' in e:
                    level += indent
            return split.join(rtn)
        else:
            return split.join(self.xml)


class FileXML(BasicXML):
    step = 1
    indent = 0
    def __init__(self, log, verbose=False):
        self.log = open(log, 'w')
        self.verbose = verbose
    def begin(self, *element):
        self._commit_('<', element, '>')
        self.indent += self.step
    def end(self, *element):
        self.indent -= self.step if self.indent > 0 else 0
        self._commit_('</', element, '>')
    def _commit_(self, head, log, tail):
        log = self._join_([' '*self.indent, head], log, [tail])
        log = log.encode('utf-8', 'replace').decode('utf-8')
        self.verbose and print(log)
        self.log.write(log +'\n')
    def __del__(self):
        self.log.close()
